package com.example.im.infra.executor.config;

import com.example.im.infra.executor.send.IBaseSendExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @author PC
 * Executor配置
 */
@Component
public class ExecutorConfiguration implements ApplicationContextAware {
    private final static Logger logger = LoggerFactory.getLogger(ExecutorConfiguration.class);

    private Map<String, IBaseSendExecutor> baseSendExecutorMap = new HashMap<>(16);

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ExecutorConfiguration.applicationContext = applicationContext;
        //加载IBaseSendExecutor实现类
        this.initBaseSendExecutor(applicationContext);
    }

    /**
     * 加载IBaseSendExecutor实现类
     * 如果一个服务的发送渠道是固定的，可以使用@Bean搭配@ConditionalOnProperty的方式
     * 但是考虑到后续可能会有一个服务不同发送渠道的场景，采用当前加载方式
     *
     * @param applicationContext 上下文
     */
    private void initBaseSendExecutor(ApplicationContext applicationContext) {
        logger.info("Start loading IBaseSendExecutor");
        Map<String, IBaseSendExecutor> baseSendExecutorMap = applicationContext.getBeansOfType(IBaseSendExecutor.class);
        for (Map.Entry<String, IBaseSendExecutor> iBaseSendExecutorEntry : baseSendExecutorMap.entrySet()) {
            String communicationType = iBaseSendExecutorEntry.getValue().getCommunicationType();
            this.baseSendExecutorMap.put(communicationType, iBaseSendExecutorEntry.getValue());
            logger.info("initBaseSendExecutor>>>>>>>communicationType:{},className:{}", communicationType, iBaseSendExecutorEntry.getValue().getClass().getName());
        }
        logger.info("IBaseSendExecutor loading is complete");
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public Map<String, IBaseSendExecutor> getBaseSendExecutorMap() {
        return baseSendExecutorMap;
    }

    public void setBaseSendExecutorMap(Map<String, IBaseSendExecutor> baseSendExecutorMap) {
        this.baseSendExecutorMap = baseSendExecutorMap;
    }
}
